package cn.tedu.charging.cost.service.impl;

import cn.tedu.charging.common.pojo.param.ProgressCostParam;
import cn.tedu.charging.common.pojo.po.ChargingCostRulePO;
import cn.tedu.charging.common.pojo.vo.ProgressCostVO;
import cn.tedu.charging.cost.repository.CostRuleRepository;
import cn.tedu.charging.cost.service.CostService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;

@Service
@Slf4j
public class CostServiceImpl implements CostService {
    @Autowired
    private CostRuleRepository costRuleRepository;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public ProgressCostVO calculateCost(ProgressCostParam cost) {
        //1.获取当前计价所属时间,得到规则时间范围判断条件 8:15同步过来的 hour=8
        int hour= LocalDateTime.now().getHour();
        //2.调用仓储层 根据设备id 设备类型 设备所属场站 时间hour查询对应CostRulePO(本次计算单价)
        ChargingCostRulePO costRule = costRuleRepository.getCostRule(cost.getStationId(), hour);
        //3.计算本次金额 第一次同步 4度计算本次 第二次同步 9度 5度计算本次
        BigDecimal currentCost=caclulateCurrentCost(cost,costRule);
        //4.利用本次 和往次的记录 计算总金额
        Double totalCost=calculateTotalCost(currentCost,cost);
        //5.封装结果返回 totalTime没计算
        ProgressCostVO vo=new ProgressCostVO();
        vo.setTotalCost(totalCost);
        vo.setPowerFee(costRule.getPowerFee().doubleValue());
        return vo;
    }

    private Double calculateTotalCost(BigDecimal currentCost, ProgressCostParam cost) {
        //1.从历史记录订单总价格读取totalCost
        String lastTotalCostKey="charging:cost:last:total:"+cost.getOrderNo();
        //判断是否有值
        ValueOperations<String,Double> stringOps = redisTemplate.opsForValue();
        Double lastTotalCost = stringOps.get(lastTotalCostKey);
        Double totalCost=null;
        if (lastTotalCost==null){
            //第一次同步
            totalCost =currentCost.doubleValue();
        }else{
            //第N次同步
            totalCost=lastTotalCost+currentCost.doubleValue();
        }
        //2.存储到redis方便下次计算 12小时超时
        stringOps.set(lastTotalCostKey,lastTotalCost);
        return totalCost;
    }

    private BigDecimal caclulateCurrentCost(ProgressCostParam cost,ChargingCostRulePO costRule) {
        //1.每张订单,只可能有有一次同步计算价格逻辑,所以使用订单编号来记录计价过程,计价结束删除
        String lastTotalCap="charging:cost:last:cap:"+cost.getOrderNo();
        //读取上次总度数记录
        ValueOperations<String,Double> stringOps = redisTemplate.opsForValue();
        Double lastCapacity = stringOps.get(lastTotalCap);
        Double capacity=null;
        //判断2个分支
        if (lastCapacity==null){
            //第一次同步
            capacity=cost.getChargingCapacity();
        }else{
            //第N次同步
            capacity=cost.getChargingCapacity()-lastCapacity;
        }
        //2.使用度数 乘以本次查询计价规则单价 Double和Double类型做加减乘除计算 有精度偏差,还成bigDecimal
        BigDecimal currentCapacity=new BigDecimal(capacity+"");
        //计算相乘,最好取 前2位小数点
        return currentCapacity.multiply(costRule.getPowerFee()).setScale(2, RoundingMode.HALF_UP);

    }
}
